package com.zeyu.framework.core.persistence.table;

import org.apache.commons.lang3.builder.ToStringBuilder;

import java.io.Serializable;
import java.util.List;

/**
 * 包含了表初始化的各种信息的扩展型TableData
 * <p>
 * 目前主要用于后台生产报表的表，包含了表生产的所有信息，后面考虑扩展到可以后台直接根据url生产表对象.
 *
 * @param <T> the generic type
 * @author zeyuphoenix
 */
public class ExtendTableData<T> implements Serializable {

    /**
     * The Constant serialVersionUID.
     */
    private static final long serialVersionUID = 1L;

    // remote 默认是远程模式
    // 本地生产表格使用false
    /**
     * The remote.
     */
    private boolean remote = false;
    // 数据请求url地址
    // 本地生产表设置为空
    /**
     * The dataurl.
     */
    private String dataurl = null;
    // 数据请求参数
    // 本地生产表设置为空
    // 由于格式多变，前端使用，请传入json字符串，由使用者转换为专有json
    /**
     * The params.
     */
    private String params = null;
    // 本地模式才生效
    /**
     * The datas.
     */
    private TableData<T> datas = null;

    // 表的标题
    /**
     * The tilte.
     */
    private String tilte = "";

    // 额外接口,必须 和表的option保持一致,不要随便覆盖
    // 由于格式多变，前端使用，请传入json字符串，由使用者转换为专有json
    /**
     * The config.
     */
    private String config = null;

    /**
     * <pre>
     * 表头和表格值的显示主要在这个属性:
     *  [{
     * 		//默认都是false，不开启可以不写开启覆盖
     * 		searchable: false,
     * 		orderable: false,
     * 	    visible: true,
     * 		render: function ( data, type, row ) {
     * 			return '<a href="'+data+'">Download</a>';
     *        },
     * 		class: "",
     * 		width: null, ////"20%" or 20px
     * 		//必须项，表头和对应json的数据
     * 		data: "",
     * 		title: ""
     *   }，
     *   {
     *   }]
     * </pre>
     */
    private List<Column> columns = null;
    // 目前考虑不配制这个属性,配置的话需要 "targets":0
    // 由于格式多变，前端使用，请传入json字符串，由使用者转换为专有json
    /**
     * The column defs.
     */
    private String columnDefs = null;

    /**
     * 默认开启检索.
     */
    private boolean searching = true;

    /**
     * 默认开启排序.
     */
    private boolean ordering = true;

    /**
     * 默认开启分页.
     */
    private boolean paging = true;

    /**
     * 默认开进度展示.
     */
    private boolean processing = true;

    /**
     * 默认远程获取数据.
     */
    private boolean serverSide = true;

    /**
     * 表的高度 -- 200px.
     */
    private String scrollY = "";

    /**
     * 是否有索引.
     */
    private boolean hasIndex = false;

    /**
     * 是否支持行选择.
     */
    private boolean hasSelect = false;

    /**
     * 是否支持多行选择.
     */
    private boolean hasMultSelect = false;

    /**
     * 是否有选择框,有选择框必然有多行选择.
     */
    private boolean hasCheck = false;

    /**
     * checkbox 绑定数据列，必须与columns的data对应.
     */
    private String checkBind = "";

    /**
     * 是否有下拉扩展.
     */
    private boolean hasDetails = false;
    /**
     * <pre>
     * 下拉框的详细
     * 目前支持html和function
     *
     * 1.html格式:
     *  details: '<div>Drop click this</div>',
     * 2.table格式:
     * details: function (row, $div, datatable) {
     *   //传入的是子DataTable的配置项，目前使用本地模式，不分页、不过滤、无cache、无选择框
     *   //覆盖传入模式，可以写入和datatable相同的配置项覆盖
     *
     *      //默认子table配置项，需要修改则覆盖
     *      var suboptions = {
     *          serverSide: false,
     *          searching: false,
     *          paging: false,
     *          hasCache: false,
     *          hasSelect: true,
     *          hasIndex: true,
     *          info: false,
     *      };
     *      //必须项目
     *      //远程模式则按照DataTable配置
     *      suboptions.databind = $div.get(0);
     *      suboptions.datas = subTableData;
     *      suboptions.columns = [
     *           { data: 'name', title: 'SubName' },
     *           { data: 'position', title: 'SubPos' },
     *           { data: 'salary', title: 'SubSal'},
     *           { data: 'office', title: 'SubOff' }
     *      ];
     *      var subDatatable = new DataTableData(suboptions);
     *      return $div.html();
     * }
     * </pre>
     */
    // 由于格式多变，前端使用，请传入json字符串，由使用者转换为专有json
    private String details = "";

    /**
     * 是否使用页面缓存.
     */
    private boolean hasCache = false;

    /**
     * 页面缓存大小.
     */
    private int cachePages = 5;

    /**
     * 刷新表格.
     */
    private String refresh = null;
    /**
     * <pre>
     * 单击行
     * 双击会触发一到两次单击，事件最好只用一个
     *   click :function(datatable, event){
     *      console.info(datatable);
     *      console.info(event);
     *   }
     * </pre>
     * <p>
     * java script 函数
     */
    private String click = null;
    /**
     * <pre>
     * 双击行
     * 双击会触发一到两次单击，事件最好只用一个
     *   dblclick :function(datatable, event){
     *      console.info(datatable);
     *      console.info(event);
     *   }
     * </pre>
     * <p>
     * java script 函数
     */
    private String dblclick = null;
    /**
     * <pre>
     * Called when the table has been initialised.
     *    initComplete: function(settings, json) {
     *          alert( 'DataTables has finished its initialisation.' );
     *    }
     * </pre>
     * <p>
     * java script 函数
     **/
    private String initComplete = null;
    /**
     * <pre>
     * This function is called on every 'draw' event, and allows you to
     * dynamically modify any aspect you want about the created DOM.
     *
     *      "     drawCallback": function( settings ) {
     *          alert( 'DataTables has redrawn the table' );
     *     }
     * </pre>
     * <p>
     * java script 函数
     */
    private String drawCallback = null;

    /**
     * Checks if is remote.
     *
     * @return true, if is remote
     */
    public boolean isRemote() {
        return remote;
    }

    /**
     * Sets the remote.
     *
     * @param remote the new remote
     */
    public void setRemote(boolean remote) {
        this.remote = remote;
    }

    /**
     * Gets the dataurl.
     *
     * @return the dataurl
     */
    public String getDataurl() {
        return dataurl;
    }

    /**
     * Sets the dataurl.
     *
     * @param dataurl the new dataurl
     */
    public void setDataurl(String dataurl) {
        this.dataurl = dataurl;
    }

    /**
     * Gets the params.
     *
     * @return the params
     */
    public String getParams() {
        return params;
    }

    /**
     * Sets the params.
     *
     * @param params the new params
     */
    public void setParams(String params) {
        this.params = params;
    }

    /**
     * Gets the datas.
     *
     * @return the datas
     */
    public TableData<T> getDatas() {
        return datas;
    }

    /**
     * Sets the datas.
     *
     * @param datas the new datas
     */
    public void setDatas(TableData<T> datas) {
        this.datas = datas;
    }

    /**
     * Gets the tilte.
     *
     * @return the tilte
     */
    public String getTilte() {
        return tilte;
    }

    /**
     * Sets the tilte.
     *
     * @param tilte the new tilte
     */
    public void setTilte(String tilte) {
        this.tilte = tilte;
    }

    /**
     * Gets the config.
     *
     * @return the config
     */
    public String getConfig() {
        return config;
    }

    /**
     * Sets the config.
     *
     * @param config the new config
     */
    public void setConfig(String config) {
        this.config = config;
    }

    /**
     * Gets the columns.
     *
     * @return the columns
     */
    public List<Column> getColumns() {
        return columns;
    }

    /**
     * Sets the columns.
     *
     * @param columns the new columns
     */
    public void setColumns(List<Column> columns) {
        this.columns = columns;
    }

    /**
     * Gets the column defs.
     *
     * @return the column defs
     */
    public String getColumnDefs() {
        return columnDefs;
    }

    /**
     * Sets the column defs.
     *
     * @param columnDefs the new column defs
     */
    public void setColumnDefs(String columnDefs) {
        this.columnDefs = columnDefs;
    }

    /**
     * Checks if is searching.
     *
     * @return true, if is searching
     */
    public boolean isSearching() {
        return searching;
    }

    /**
     * Sets the searching.
     *
     * @param searching the new searching
     */
    public void setSearching(boolean searching) {
        this.searching = searching;
    }

    /**
     * Checks if is ordering.
     *
     * @return true, if is ordering
     */
    public boolean isOrdering() {
        return ordering;
    }

    /**
     * Sets the ordering.
     *
     * @param ordering the new ordering
     */
    public void setOrdering(boolean ordering) {
        this.ordering = ordering;
    }

    /**
     * Checks if is paging.
     *
     * @return true, if is paging
     */
    public boolean isPaging() {
        return paging;
    }

    /**
     * Sets the paging.
     *
     * @param paging the new paging
     */
    public void setPaging(boolean paging) {
        this.paging = paging;
    }

    /**
     * Checks if is processing.
     *
     * @return true, if is processing
     */
    public boolean isProcessing() {
        return processing;
    }

    /**
     * Sets the processing.
     *
     * @param processing the new processing
     */
    public void setProcessing(boolean processing) {
        this.processing = processing;
    }

    /**
     * Checks if is server side.
     *
     * @return true, if is server side
     */
    public boolean isServerSide() {
        return serverSide;
    }

    /**
     * Sets the server side.
     *
     * @param serverSide the new server side
     */
    public void setServerSide(boolean serverSide) {
        this.serverSide = serverSide;
    }

    /**
     * Gets the scroll y.
     *
     * @return the scroll y
     */
    public String getScrollY() {
        return scrollY;
    }

    /**
     * Sets the scroll y.
     *
     * @param scrollY the new scroll y
     */
    public void setScrollY(String scrollY) {
        this.scrollY = scrollY;
    }

    /**
     * Checks if is checks for index.
     *
     * @return true, if is checks for index
     */
    public boolean isHasIndex() {
        return hasIndex;
    }

    /**
     * Sets the checks for index.
     *
     * @param hasIndex the new checks for index
     */
    public void setHasIndex(boolean hasIndex) {
        this.hasIndex = hasIndex;
    }

    /**
     * Checks if is checks for select.
     *
     * @return true, if is checks for select
     */
    public boolean isHasSelect() {
        return hasSelect;
    }

    /**
     * Sets the checks for select.
     *
     * @param hasSelect the new checks for select
     */
    public void setHasSelect(boolean hasSelect) {
        this.hasSelect = hasSelect;
    }

    /**
     * Checks if is checks for mult select.
     *
     * @return true, if is checks for mult select
     */
    public boolean isHasMultSelect() {
        return hasMultSelect;
    }

    /**
     * Sets the checks for mult select.
     *
     * @param hasMultSelect the new checks for mult select
     */
    public void setHasMultSelect(boolean hasMultSelect) {
        this.hasMultSelect = hasMultSelect;
    }

    /**
     * Checks if is checks for check.
     *
     * @return true, if is checks for check
     */
    public boolean isHasCheck() {
        return hasCheck;
    }

    /**
     * Sets the checks for check.
     *
     * @param hasCheck the new checks for check
     */
    public void setHasCheck(boolean hasCheck) {
        this.hasCheck = hasCheck;
    }

    /**
     * Checks if is check bind.
     *
     * @return true, if is check bind
     */
    public String getCheckBind() {
        return checkBind;
    }

    /**
     * Sets the check bind.
     *
     * @param checkBind the new check bind
     */
    public void setCheckBind(String checkBind) {
        this.checkBind = checkBind;
    }

    /**
     * Checks if is checks for details.
     *
     * @return true, if is checks for details
     */
    public boolean isHasDetails() {
        return hasDetails;
    }

    /**
     * Sets the checks for details.
     *
     * @param hasDetails the new checks for details
     */
    public void setHasDetails(boolean hasDetails) {
        this.hasDetails = hasDetails;
    }

    /**
     * Gets the details.
     *
     * @return the details
     */
    public String getDetails() {
        return details;
    }

    /**
     * Sets the details.
     *
     * @param details the new details
     */
    public void setDetails(String details) {
        this.details = details;
    }

    /**
     * Checks if is checks for cache.
     *
     * @return true, if is checks for cache
     */
    public boolean isHasCache() {
        return hasCache;
    }

    /**
     * Sets the checks for cache.
     *
     * @param hasCache the new checks for cache
     */
    public void setHasCache(boolean hasCache) {
        this.hasCache = hasCache;
    }

    /**
     * Gets the cache pages.
     *
     * @return the cache pages
     */
    public int getCachePages() {
        return cachePages;
    }

    /**
     * Sets the cache pages.
     *
     * @param cachePages the new cache pages
     */
    public void setCachePages(int cachePages) {
        this.cachePages = cachePages;
    }

    /**
     * Gets the refresh.
     *
     * @return the refresh
     */
    public String getRefresh() {
        return refresh;
    }

    /**
     * Sets the refresh.
     *
     * @param refresh the new refresh
     */
    public void setRefresh(String refresh) {
        this.refresh = refresh;
    }

    /**
     * Gets the click.
     *
     * @return the click
     */
    public String getClick() {
        return click;
    }

    /**
     * Sets the click.
     *
     * @param click the new click
     */
    public void setClick(String click) {
        this.click = click;
    }

    /**
     * Gets the dblclick.
     *
     * @return the dblclick
     */
    public String getDblclick() {
        return dblclick;
    }

    /**
     * Sets the dblclick.
     *
     * @param dblclick the new dblclick
     */
    public void setDblclick(String dblclick) {
        this.dblclick = dblclick;
    }

    /**
     * Gets the inits the complete.
     *
     * @return the inits the complete
     */
    public String getInitComplete() {
        return initComplete;
    }

    /**
     * Sets the inits the complete.
     *
     * @param initComplete the new inits the complete
     */
    public void setInitComplete(String initComplete) {
        this.initComplete = initComplete;
    }

    /**
     * Gets the draw callback.
     *
     * @return the draw callback
     */
    public String getDrawCallback() {
        return drawCallback;
    }

    /**
     * Sets the draw callback.
     *
     * @param drawCallback the new draw callback
     */
    public void setDrawCallback(String drawCallback) {
        this.drawCallback = drawCallback;
    }

    /**
     * 表头和表格属性
     * <p>
     * <pre>
     * {
     *      //默认都是false，不开启可以不写开启覆盖
     *      searchable: false,
     *      orderable: false,
     *      visible: true,
     *      render: function ( data, type, row ) {
     *            return '<a href="'+data+'">Download</a>';
     *      },
     *      class: "",
     *      width: null, ////"20%" or 20px
     *      //必须项，表头和对应json的数据
     *      data: "",
     *      title: ""
     *  }
     * </pre>
     *
     * @author zeyuphoenix
     */
    public static class Column {
        // 默认都是false，不开启可以不写开启覆盖
        /**
         * The searchable.
         */
        private boolean searchable = false;

        /**
         * The orderable.
         */
        private boolean orderable = false;

        /**
         * The visible.
         */
        private boolean visible = true;
        // java script 函数
        /**
         * The render.
         */
        private String render;

        /**
         * The class col.
         */
        private String classCol = "";
        // //"20%" or 20px
        /**
         * The width.
         */
        private String width = null;
        // 必须项，表头和对应json的数据
        /**
         * The data.
         */
        private String data = "";

        /**
         * The title.
         */
        private String title = "";

        /**
         * Checks if is searchable.
         *
         * @return true, if is searchable
         */
        public boolean isSearchable() {
            return searchable;
        }

        /**
         * Sets the searchable.
         *
         * @param searchable the new searchable
         */
        public void setSearchable(boolean searchable) {
            this.searchable = searchable;
        }

        /**
         * Checks if is orderable.
         *
         * @return true, if is orderable
         */
        public boolean isOrderable() {
            return orderable;
        }

        /**
         * Sets the orderable.
         *
         * @param orderable the new orderable
         */
        public void setOrderable(boolean orderable) {
            this.orderable = orderable;
        }

        /**
         * Checks if is visible.
         *
         * @return true, if is visible
         */
        public boolean isVisible() {
            return visible;
        }

        /**
         * Sets the visible.
         *
         * @param visible the new visible
         */
        public void setVisible(boolean visible) {
            this.visible = visible;
        }

        /**
         * Gets the render.
         *
         * @return the render
         */
        public String getRender() {
            return render;
        }

        /**
         * Sets the render.
         *
         * @param render the new render
         */
        public void setRender(String render) {
            this.render = render;
        }

        /**
         * Gets the class col.
         *
         * @return the class col
         */
        public String getClassCol() {
            return classCol;
        }

        /**
         * Sets the class col.
         *
         * @param classCol the new class col
         */
        public void setClassCol(String classCol) {
            this.classCol = classCol;
        }

        /**
         * Gets the width.
         *
         * @return the width
         */
        public String getWidth() {
            return width;
        }

        /**
         * Sets the width.
         *
         * @param width the new width
         */
        public void setWidth(String width) {
            this.width = width;
        }

        /**
         * Gets the data.
         *
         * @return the data
         */
        public String getData() {
            return data;
        }

        /**
         * Sets the data.
         *
         * @param data the new data
         */
        public void setData(String data) {
            this.data = data;
        }

        /**
         * Gets the title.
         *
         * @return the title
         */
        public String getTitle() {
            return title;
        }

        /**
         * Sets the title.
         *
         * @param title the new title
         */
        public void setTitle(String title) {
            this.title = title;
        }

        /*
         * (non-Javadoc)
         *
         * @see java.lang.Object#toString()
         */
        @Override
        public String toString() {
            return ToStringBuilder.reflectionToString(this);
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
}
